package com.ruoyi.framework.config;

import com.alibaba.cloud.spring.boot.context.env.AliCloudProperties;
import com.aliyun.oss.OSS;
import com.aliyun.oss.common.utils.BinaryUtil;
import com.aliyun.oss.model.MatchMode;
import com.aliyun.oss.model.PolicyConditions;
import com.aliyun.oss.model.PutObjectResult;
import com.ruoyi.framework.config.properties.AliossPropertis;
import com.ruoyi.framework.utils.FileDyUtils;
import org.springframework.boot.autoconfigure.condition.ConditionalOnProperty;
import org.springframework.boot.context.properties.EnableConfigurationProperties;
import org.springframework.context.annotation.Configuration;
import org.springframework.util.StringUtils;
import org.springframework.web.multipart.MultipartFile;

import java.io.IOException;
import java.nio.charset.StandardCharsets;
import java.util.Date;
import java.util.LinkedHashMap;
import java.util.Map;

import static com.alibaba.cloud.spring.boot.oss.OssConstants.PREFIX;

/**
 * @author dyun
 */
@Configuration
@ConditionalOnProperty(prefix = PREFIX, name = "enabled", matchIfMissing = true)
@EnableConfigurationProperties(AliossPropertis.class)
public class AliossConfig {
    public static OSS ossClient;

    private static AliCloudProperties aliCloudProperties;

    private static AliossPropertis aliossPropertis;

    public AliossConfig(OSS ossClient, AliCloudProperties aliCloudProperties, AliossPropertis aliossPropertis) {
        AliossConfig.ossClient = ossClient;
        AliossConfig.aliCloudProperties = aliCloudProperties;
        AliossConfig.aliossPropertis = aliossPropertis;
    }

    /**
     * 根据默认文件路径上传
     *
     * @param file 上传的文件
     * @return 成功返回文件路径，失败返回""
     * @throws IOException exception
     */
    public static String upload(MultipartFile file) throws IOException {
        return upload(file, FileDyUtils.getUploadPath() + FileDyUtils.renameFile(file.getOriginalFilename()));
    }

    /**
     * 根据指定文件路径上传
     *
     * @param file 上传的文件
     * @return 成功返回文件路径，失败返回""
     * @throws IOException exception
     */
    public static String upload(MultipartFile file, String fileKey) throws IOException {
        String bucketName = aliossPropertis.getBucketName();
        PutObjectResult p = ossClient.putObject(bucketName, fileKey, file.getInputStream());

        // 公共读
        if (!StringUtils.isEmpty(p.getETag())) {
            return aliossPropertis.getHost() + "/" + fileKey;
        }

        return "";
    }

    /**
     * 获取alioss policy
     *
     * @return policy postparam
     */
    public static Map<String, String> getPolicy() {
        String baseDir = FileDyUtils.getUploadPath();
        long expireEndTime = System.currentTimeMillis() + aliossPropertis.getExpireTime() * 1000;
        Date expiration = new Date(expireEndTime);

        PolicyConditions policyConds = new PolicyConditions();
        policyConds.addConditionItem(PolicyConditions.COND_CONTENT_LENGTH_RANGE, 0, aliossPropertis.getMaxFileSize().toBytes());
        policyConds.addConditionItem(MatchMode.StartWith, PolicyConditions.COND_KEY, baseDir);

        String postPolicy = ossClient.generatePostPolicy(expiration, policyConds);
        byte[] binaryData = postPolicy.getBytes(StandardCharsets.UTF_8);
        String encodedPolicy = BinaryUtil.toBase64String(binaryData);
        String postSignature = ossClient.calculatePostSignature(postPolicy);

        Map<String, String> respMap = new LinkedHashMap<>(16);
        respMap.put("OSSAccessKeyId", aliCloudProperties.getAccessKey());
        respMap.put("policy", encodedPolicy);
        respMap.put("signature", postSignature);
        respMap.put("dir", baseDir);
        respMap.put("key", baseDir + "${filename}");
        respMap.put("host", aliossPropertis.getHost());
        respMap.put("expire", String.valueOf(expireEndTime / 1000));

        return respMap;
    }
}
